#ifndef GRAMMARSYMBOL_H
#define GRAMMARSYMBOL_H

#include <string>
#include <memory>
#include "Symbol.h"

class GrammarSymbol {
public:
    std::string name;   // 名字
    SymbolType type;    // 类别
    GrammarSymbol(std::string n = "ε", SymbolType t = SymbolType::EPSILON)
        : name(std::move(n)), type(t) {}
    string get_name() const{
        return name;
    }
};


class TerminalSymbol : public GrammarSymbol {
public:
    LexemeCategory category;    // 词类别
    //std::set<TerminalSymbol*> follow_set;       // FOLLOW集合
    TerminalSymbol(std::string name = "ε", LexemeCategory lexemeCategory = LexemeCategory::INTEGER_CONST)
        : GrammarSymbol(std::move(name), SymbolType::TERMINAL), category(lexemeCategory) {

    }
};

class NonTerminalSymbol : public GrammarSymbol {
public:
    std::shared_ptr<NonTerminalSymbol> linked_non_terminal;

    std::list<int> production_table;           // 产生式表
    std::set<TerminalSymbol*> first_set;        // FIRST集合
    std::set<TerminalSymbol*> follow_set;       // FOLLOW集合
    std::set<NonTerminalSymbol*> dependent_set_in_follow;    // 依赖的非终结符集合

    NonTerminalSymbol(std::string n = "")
        : GrammarSymbol(n, SymbolType::NON_TERMINAL) {}

    void add_production(int pro);
    void calcu_first();
    void calcu_follow();
    void calcu_follow_pre();
    void get_info();
};

extern TerminalSymbol epsilo;


#endif // GRAMMARSYMBOL_H
